/*
 * Copyright 2011 Clean GWT
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cleangwt.uibinder.rebind;

import java.util.ArrayList;
import java.util.List;

import com.cleangwt.uibinder.client.UiField;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.user.rebind.SourceWriter;

/**
 * A helper for template rebinding.
 * 
 * @author Jess
 * @version 1.0
 * @since 1.0
 */
public class TemplateRebindHelper {

  /**
   * Creates not-null-element assertion for respective fields.
   * 
   * @param sw the source writer
   * @param uiFields the ui fields with {@link UiField}
   */
  static void createNotNullAssertion(SourceWriter sw, List<JField> uiFields) {
    for (JField field : uiFields) {
      sw.println("assert template.getElementById(\"%s\") != null : "
          + "\"Did you forget to specify the id \'%s\' to an element in your html template?\";",
          field.getName(), field.getName());
    }
  }

  /**
   * Instantiates declared fields.
   * 
   * @param sw the source writer
   * @param uiFields the ui fields with {@link UiField}
   */
  static void createOrReplaceFields(SourceWriter sw, List<JField> uiFields) {
    for (JField field : uiFields) {
      UiField uiField = field.getAnnotation(UiField.class);
      if (!uiField.provided()) {
        JClassType fieldType = field.getType().isClass();
        sw.println("%s = %s.wrap(template,template.getElementById(\"%s\"));", field.getName(),
            fieldType.getSimpleSourceName(), field.getName());
      } else {
        sw.println("template.addAndReplaceElement(%s,template.getElementById(\"%s\"));", field
            .getName(), field.getName());
      }
    }
  }

  static List<JField> findUiFields(JClassType binderType) {
    List<JField> fields = new ArrayList<JField>();
    for (JField field : binderType.getFields()) {
      if (field.isAnnotationPresent(UiField.class)) {
        fields.add(field);
      }
    }
    return fields;
  }

}
